import SwiftUI

struct ManualEncryptionView: View {
    let user: User?
    
    @State private var inputDirectory: URL?
    @State private var outputDirectory: URL?
    @State private var selectedLicenseProfile: LicenseProfile? = nil
    @State private var createFolders: Bool = true
    @State private var files: [FileItem] = []
    @State private var isProcessing: Bool = false
    @State private var shouldCancel: Bool = false
    @State private var showingInputDirectoryPicker = false
    @State private var showingOutputDirectoryPicker = false
    @State private var licenseProfiles: [LicenseProfile] = []
    @State private var isLoadingLicenseProfiles = false
    @State private var selectedFileID: UUID? = nil
    
    @State private var windowDelegate: WindowDelegate? = nil
    
    @State private var inputDirectoryScopedAccess: Bool = false
    @State private var outputDirectoryScopedAccess: Bool = false
    
    struct LicenseProfile: Identifiable, Hashable {
        let id: String
        let name: String
    }
    
    private var serviceURL: String {
        user?.isChineseVersion ?? false ? "https://4.drm-x.cn/haihaisoftlicenseservice.asmx" : "https://4.drm-x.com/haihaisoftlicenseservice.asmx"
    }
    
    private var soapAction: String {
        user?.isChineseVersion ?? false ? "https://4.drm-x.cn/haihaisoftlicenseservice.asmx?op=ListLicenseProfilesAsString" : "https://4.drm-x.com/haihaisoftlicenseservice.asmx?op=ListLicenseProfilesAsString"
    }
    
    // MARK: - 界面布局入口-View Body
    var body: some View {
        let isChinese = user?.isChineseVersion ?? false
        VStack(spacing: 16) {
            //MARK: 输入目录选择
            HStack {
                Text(localized("input_directory", isChinese: isChinese))
                    .frame(width: 110, alignment: .leading)
                
                TextField(localized("select_input_directory", isChinese: isChinese), text: Binding(
                    get: { inputDirectory?.path ?? "" },
                    set: { _ in }
                ))
                .disabled(true)
                
                Button(localized("browse", isChinese: isChinese)) {
                    showingInputDirectoryPicker = true
                }
                .fileImporter(
                    isPresented: $showingInputDirectoryPicker,
                    allowedContentTypes: [.folder],
                    allowsMultipleSelection: false
                ) { result in
                    switch result {
                    case .success(let urls):
                        if let url = urls.first {
                            inputDirectory?.stopAccessingSecurityScopedResource()
                            inputDirectory = url
                            inputDirectoryScopedAccess = url.startAccessingSecurityScopedResource()
                            loadFiles()
                        }
                    case .failure(let error):
                        print("选择目录失败: \(error.localizedDescription)")
                    }
                }
            }
            
            //MARK: 输出目录选择
            HStack {
                Text(localized("output_directory", isChinese: isChinese))
                    .frame(width: 110, alignment: .leading)
                
                TextField(localized("select_output_directory", isChinese: isChinese), text: Binding(
                    get: { outputDirectory?.path ?? "" },
                    set: { _ in }
                ))
                .disabled(true)
                
                Button(localized("browse", isChinese: isChinese)) {
                    showingOutputDirectoryPicker = true
                }
                .fileImporter(
                    isPresented: $showingOutputDirectoryPicker,
                    allowedContentTypes: [.folder],
                    allowsMultipleSelection: false
                ) { result in
                    switch result {
                    case .success(let urls):
                        if let url = urls.first {
                            outputDirectory?.stopAccessingSecurityScopedResource()
                            outputDirectory = url
                            outputDirectoryScopedAccess = url.startAccessingSecurityScopedResource()
                        }
                    case .failure(let error):
                        print("选择目录失败: \(error.localizedDescription)")
                    }
                }
            }
            
            //MARK: 许可证模板选择
            HStack {
                Text(localized("license_profile", isChinese: isChinese))
                    .frame(width: 110, alignment: .leading)
                
                if isLoadingLicenseProfiles {
                    ProgressView()
                } else {
                    Picker("", selection: $selectedLicenseProfile) {
                        ForEach(licenseProfiles, id: \.self) { licenseProfile in
                            Text("\(licenseProfile.id) || \(licenseProfile.name)").tag(licenseProfile as LicenseProfile?)
                        }
                    }
                    .frame(maxWidth: .infinity, alignment: .leading)
                }
            }
            
            Toggle(localized("create_folder_toggle", isChinese: isChinese), isOn: $createFolders)
                .frame(maxWidth: .infinity, alignment: .leading)
            
            //MARK: 文件列表
            List(selection: $selectedFileID) {
                // 表头行
                HStack {
                    Text(localized("file_name", isChinese: isChinese)).font(.headline).frame(width: 200, alignment: .leading)
                    Text(localized("input_path", isChinese: isChinese)).font(.headline).frame(width: 180, alignment: .leading)
                    Text(localized("output_path", isChinese: isChinese)).font(.headline).frame(width: 180, alignment: .leading)
                    Text(localized("file_size", isChinese: isChinese)).font(.headline).frame(width: 80, alignment: .leading)
                    Text(localized("status", isChinese: isChinese)).font(.headline).frame(width: 140, alignment: .leading)
                }
                .padding(.vertical, 4)
                
                //MARK: 文件数据行
                ForEach(files) { file in
                    HStack {
                        Text(file.name)
                            .frame(width: 200, alignment: .leading)
                            .lineLimit(1)
                            .help(file.name)
                        
                        Text(file.inputPath)
                            .frame(width: 180, alignment: .leading)
                            .lineLimit(1)
                            .help(file.inputPath)
                        
                        Text(file.outputPath.isEmpty ? localized("auto_generated", isChinese: isChinese) : file.outputPath)
                            .frame(width: 180, alignment: .leading)
                            .foregroundColor(file.outputPath.isEmpty ? .gray : .primary)
                            .lineLimit(1)
                            .help(file.outputPath.isEmpty ? localized("tooltip_auto_generate", isChinese: isChinese) : file.outputPath)
                        
                        Text(file.formattedSize)
                            .frame(width: 80, alignment: .leading)
                        
                        Text(file.status.localizedString(isChinese: user?.isChineseVersion ?? false))
                            .frame(width: 140, alignment: .leading)
                            .foregroundColor(statusColor(for: file.status))
                    }
                    .padding(.vertical, 2)
                    .tag(file.id)
                    .contentShape(Rectangle()) // 让整行都可以被点击
                    .listRowInsets(EdgeInsets(top: 0, leading: 0, bottom: 0, trailing: 0))
                    .onTapGesture {
                        selectedFileID = file.id
                    }
                    .simultaneousGesture(
                        TapGesture(count: 2).onEnded { // 双击打开
                            selectedFileID = file.id
                            openFile(url: URL(fileURLWithPath: file.inputPath))
                        }
                    )
                    .contextMenu {
                        Button(localized("refresh", isChinese: isChinese)) {
                            selectedFileID = file.id // 右键时选中
                            loadFiles()
                        }
                        Button(localized("open_input_folder", isChinese: isChinese)) {
                            selectedFileID = file.id
                            openFolder(url: URL(fileURLWithPath: file.inputPath))
                        }
                        Button(localized("open_output_folder", isChinese: isChinese)) {
                            selectedFileID = file.id
                            if !file.outputPath.isEmpty {
                                openFolder(url: URL(fileURLWithPath: file.outputPath))
                            }
                        }
                    }

                    .background(
                        selectedFileID == file.id ? Color.blue.opacity(0.2) : Color.clear
                    )
                }
            }
            .frame(maxHeight: .infinity)
            .listStyle(PlainListStyle())
            .padding(.horizontal, 0)
            .padding(.top, 0)
            
            //MARK: 开始-取消按钮
            HStack {
                Button(action: startEncryption) {
                    if isProcessing {
                        ProgressView()
                    } else {
                        Text(localized("start_encryption", isChinese: isChinese))
                            .frame(width: 100, height: 30)
                    }
                }
                .disabled(isProcessing || files.isEmpty || selectedLicenseProfile == nil)
                .buttonStyle(.borderedProminent)
                
                Button(action: cancelEncryption) {
                    Text(localized("cancel_encryption", isChinese: isChinese))
                        .frame(width: 100, height: 30)
                }
                .disabled(!isProcessing)
                .buttonStyle(.bordered)
            }
            .padding(.top, 8)
        }
        .padding()
        .onAppear {
        loadLicenseProfiles()
        // 设置窗口代理
        DispatchQueue.main.async {
            if let window = NSApplication.shared.windows.first(where: { $0.isKeyWindow }) {
                let isChinese = user?.isChineseVersion ?? false
                self.windowDelegate = WindowDelegate(
                    isProcessing: isProcessing, 
                    isChinese: isChinese,
                    taskType: .manualEncryption,
                    onWindowClose: {
                        // 设置取消标志
                        self.shouldCancel = true
                        
                        // 等待当前任务完成
                        DispatchQueue.global(qos: .background).async {
                            // 等待当前处理完成
                            while self.isProcessing {
                                Thread.sleep(forTimeInterval: 0.1)
                            }
                        }
                    }
                )
                window.delegate = self.windowDelegate
                
                // 监听 isProcessing 状态变化
                NotificationCenter.default.addObserver(forName: NSNotification.Name("ProcessingStatusChanged"), object: nil, queue: .main) { notification in
                    if let isProcessing = notification.userInfo?["isProcessing"] as? Bool {
                        self.windowDelegate = WindowDelegate(
                            isProcessing: isProcessing, 
                            isChinese: isChinese,
                            taskType: .manualEncryption,
                            onWindowClose: {
                                // 设置取消标志
                                self.shouldCancel = true
                                
                                // 等待当前任务完成
                                DispatchQueue.global(qos: .background).async {
                                    // 等待当前处理完成
                                    while self.isProcessing {
                                        Thread.sleep(forTimeInterval: 0.1)
                                    }
                                }
                            }
                        )
                        window.delegate = self.windowDelegate
                    }
                }
            }
        }
    }
        .onDisappear {
            if inputDirectoryScopedAccess {
                inputDirectory?.stopAccessingSecurityScopedResource()
            }
            if outputDirectoryScopedAccess {
                outputDirectory?.stopAccessingSecurityScopedResource()
            }
        }
    }
    // 在 isProcessing 变化时发送通知
    private func updateProcessingStatus() {
        NotificationCenter.default.post(
            name: NSNotification.Name("ProcessingStatusChanged"),
            object: nil,
            userInfo: ["isProcessing": isProcessing]
        )
    }

    // MARK: 加载许可证模板
    private func loadLicenseProfiles() {
        isLoadingLicenseProfiles = true
        let client = SOAPClient()
        client.listLicenseProfiles(
            endpoint: serviceURL,
            soapAction: soapAction,
            adminemail: user?.adminemail ?? "",
            authStr: user?.webServiceCode ?? ""
        ) { result in
            DispatchQueue.main.async {
                isLoadingLicenseProfiles = false
                if let result = result {
                    // 解析权限字符串，格式应该是 "ID,名称;ID,名称;..."
                    let licenseProfileList = result.components(separatedBy: ";;")
                        .map { $0.trimmingCharacters(in: .whitespacesAndNewlines) }
                        .filter { !$0.isEmpty }
                    
                    // 将每个权限字符串解析为 ID 和名称
                    self.licenseProfiles = licenseProfileList.compactMap { profileStr -> LicenseProfile? in
                        let parts = profileStr.components(separatedBy: "||")
                        if parts.count >= 2 {
                            return LicenseProfile(id: parts[0], name: parts[1])
                        }
                        return nil
                    }
                    
                    // 如果有权限，默认选择第一个
                    if !self.licenseProfiles.isEmpty {
                        self.selectedLicenseProfile = self.licenseProfiles[0]
                        //print("已选择权限: ID=\(self.selectedRight!.id), 名称=\(self.selectedRight!.name)")
                    }
                } else {
                    print("获取许可证模板失败")
                }
            }
        }
    }

    // MARK: 加载文件
    private func loadFiles() {
        guard let inputDir = inputDirectory else { return }
        
        let securityScoped = inputDir.startAccessingSecurityScopedResource()
        defer {
            if securityScoped {
                inputDir.stopAccessingSecurityScopedResource()
            }
        }
        
        let fileManager = FileManager.default
        var allFiles: [FileItem] = []
        
        func scanDirectory(_ dir: URL) {
            do {
                let fileURLs = try fileManager.contentsOfDirectory(at: dir, includingPropertiesForKeys: [.fileSizeKey], options: [.skipsHiddenFiles])
                
                for url in fileURLs {
                    var isDirectory: ObjCBool = false
                    fileManager.fileExists(atPath: url.path, isDirectory: &isDirectory)
                    
                    if isDirectory.boolValue {
                        scanDirectory(url)
                    } else {
                        guard ["mp3", "mp4", "pdf"].contains(url.pathExtension.lowercased()) else { continue }
                        
                        let size = (try? url.resourceValues(forKeys: [.fileSizeKey]).fileSize) ?? 0
                        
                        let fileItem = FileItem(
                            name: url.lastPathComponent,
                            inputPath: url.path,
                            outputPath: "",
                            inputURL: url,
                            outputURL: nil,
                            size: Int64(size)
                        )
                        allFiles.append(fileItem)
                    }
                }
            } catch {
                print("扫描目录失败: \(error)")
            }
        }
        
        scanDirectory(inputDir)
        files = allFiles
    }


    // MARK: 开始加密
    private func startEncryption() {
        isProcessing = true
        updateProcessingStatus()

        guard let inputDir = inputDirectory,
              let outputDir = outputDirectory,
              !files.isEmpty  else { return }
        
        shouldCancel = false
        isProcessing = true
        
        let licenseID = selectedLicenseProfile?.id ?? ""
        let domain = user?.isChineseVersion ?? false ? "CN" : "COM"
        let adminEmail = user?.adminemail ?? ""
        let authStr = user?.webServiceCode ?? ""
        
        let securityScoped = outputDir.startAccessingSecurityScopedResource()
        defer {
            if securityScoped {
                outputDir.stopAccessingSecurityScopedResource()
            }
        }
        
        var targetOutputDir = outputDir
        
        if createFolders {
            let folderName = inputDir.lastPathComponent
            let targetFolderName = "\(licenseID)_\(folderName)"
            targetOutputDir = outputDir.appendingPathComponent(targetFolderName)
            
            if !FileManager.default.fileExists(atPath: targetOutputDir.path) {
                do {
                    try FileManager.default.createDirectory(at: targetOutputDir, withIntermediateDirectories: true)
                } catch {
                    print("❌ 创建输出子文件夹失败: \(error.localizedDescription)")
                    isProcessing = false
                    return
                }
            }
        }
        
        // 并发执行加密任务
        DispatchQueue.global(qos: .userInitiated).async {
            for i in files.indices {
                // 检查是否取消
                if shouldCancel {
                    DispatchQueue.main.async {
                        files[i].status = .pending
                        isProcessing = false
                    }
                    break
                }
                
                DispatchQueue.main.async {
                    files[i].status = .processing
                }

                let file = files[i]
                let inputURL = URL(fileURLWithPath: file.inputPath)
                
                // 计算输入相对路径（用于保留目录结构）
                let relativePath = inputURL.path.replacingOccurrences(of: inputDir.path, with: "")
                let relativeURL = URL(fileURLWithPath: relativePath)
                let relativeDir = relativeURL.deletingLastPathComponent().path
                let outputFolder = targetOutputDir.appendingPathComponent(relativeDir)
    
                // 创建输出子目录
                do {
                    try FileManager.default.createDirectory(at: outputFolder, withIntermediateDirectories: true)
                } catch {
                    DispatchQueue.main.async {
                        files[i].status = .failed
                        files[i].errorMessage = "创建目录失败: \(error.localizedDescription)"
                        if i == files.count - 1 {
                            isProcessing = false
                        }
                    }
                    continue
                }
                
                // 构造输出文件名（加 _P 后缀）
                let fileName = inputURL.deletingPathExtension().lastPathComponent + "_P"
                let fileExtension = inputURL.pathExtension
                let outputFileName = fileName + "." + fileExtension
                let outputPath = outputFolder.appendingPathComponent(outputFileName).path

                guard let mp4encryptPath = Bundle.main.resourceURL?.appendingPathComponent("mp4encrypt").path else {
                    DispatchQueue.main.async {
                        files[i].status = .failed
                        files[i].errorMessage = "无法找到 mp4encrypt 可执行文件"
                        if i == files.count - 1 {
                            isProcessing = false
                        }
                    }
                    return
                }

                let command = [
                    mp4encryptPath,
                    "-ServerDomain", domain,
                    "-AdminEmail", adminEmail,
                    "-WebServiceAuthStr", authStr,
                    "-ID", licenseID,
                    "-Input", file.inputPath,
                    "-Output", outputPath
                ]

                let process = Process()
                process.executableURL = URL(fileURLWithPath: command[0])
                process.arguments = Array(command.dropFirst())

                let pipe = Pipe()
                process.standardError = pipe
                process.standardOutput = pipe

                do {
                    try process.run()
                    process.waitUntilExit()

                    DispatchQueue.main.async {
                        if process.terminationStatus == 0 {
                            files[i].outputPath = outputPath
                            files[i].status = .completed
                        } else {
                            let errorData = pipe.fileHandleForReading.readDataToEndOfFile()
                            let errorMessage = String(data: errorData, encoding: .utf8) ?? "unknown error"
                            files[i].status = .failed
                            files[i].errorMessage = errorMessage
                            print("加密失败: \(errorMessage)")
                        }

                        // 检查是否是最后一个文件或者是否已取消
                        if i == files.count - 1 || shouldCancel {
                            isProcessing = false
                        }
                    }
                } catch {
                    DispatchQueue.main.async {
                        files[i].status = .failed
                        files[i].errorMessage = error.localizedDescription
                        print("加密失败: \(error.localizedDescription)")
                        
                        // 检查是否是最后一个文件或者是否已取消
                        if i == files.count - 1 || shouldCancel {
                            isProcessing = false
                        }
                    }
                }
            }
        }
    }

    // MARK: 取消加密
    private func cancelEncryption() {
        let isChinese = user?.isChineseVersion ?? false
        
        // 创建确认对话框
        let alert = NSAlert()
        alert.messageText = localized("cancel_confirmation_title", isChinese: isChinese)
        alert.informativeText = localized("cancel_confirmation_message", isChinese: isChinese)
        alert.alertStyle = .warning
        alert.addButton(withTitle: localized("confirm", isChinese: isChinese))
        alert.addButton(withTitle: localized("cancel", isChinese: isChinese))
        
        let response = alert.runModal()
        
        if response == .alertFirstButtonReturn {
            // 用户点击了确认按钮
            shouldCancel = true
            
            // 将所有正在处理的文件状态重置为待处理
            files = files.map { file in
                var updatedFile = file
                if updatedFile.status == .processing {
                    updatedFile.status = .pending
                }
                return updatedFile
            }
            
            // 显示已取消的提示信息
            let notification = NSAlert()
            notification.messageText = localized("cancel_success_title", isChinese: isChinese)
            notification.informativeText = localized("cancel_success_message", isChinese: isChinese)
            notification.alertStyle = .informational
            notification.addButton(withTitle: localized("ok", isChinese: isChinese))
            notification.runModal()
        }
        isProcessing = false
        updateProcessingStatus()
    }
    
    // MARK: 设置各种状态颜色
    private func statusColor(for status: FileStatus) -> Color {
        switch status {
        case .pending: return .primary
        case .processing: return .blue
        case .completed: return .green
        case .failed: return .red
        }
    }
    
    // MARK: 打开文件
    private func openFile(url: URL?) {
        guard let url = url else { return }
        NSWorkspace.shared.open(url)
    }

    // MARK: 打开文件夹并选中文件
    private func openFolder(url: URL?) {
        guard let url = url else { return }
        // 获取文件路径和文件夹路径
        let filePath = url.path
        let folderPath = url.deletingLastPathComponent().path
        
        // 使用NSWorkspace的selectFile方法打开文件夹并选中文件
        NSWorkspace.shared.selectFile(filePath, inFileViewerRootedAtPath: folderPath)
    }
}
